<?php

/**
 * 快钱支付接口类
 * 
 */

namespace payment;

class kqpay
{

    /**
     * 生产环境中快钱支付网关地址
     */
    private $payUrl = 'https://www.99bill.com/gateway/recvMerchantInfoAction.htm';

    /**
     * 支付接口标识
     *
     * @var string
     */
    private $code = 'kqpay';

    /**
     * 支付接口配置信息
     *
     * @var array
     */
    private $payment;

    /**
     * 支付订单信息
     */
    private $order;

    /**
     * 发送至快钱的参数
     *
     * @var array
     */
    private $parameter;

    /**
     * 服务器接收快钱支付结果地址 recieve的地址
     */
    private $bgUrl =  '';
    
    /**
     * 成功支付后  show的地址，先recieve,在recieve中show
     */
    private $rtnUrl = '';
    
    /**
     * 支付状态
     */
    private $pay_result;

    public function __construct($payment_info, $order_info)
    {
        $this->kqpay($payment_info, $order_info);
    }

    public function kqpay($payment_info = array(), $order_info = array())
    {
        if (!empty($payment_info) and ! empty($order_info)) {
            $this->payment = $payment_info;
            $this->order = $order_info;
        }
        $this->bgUrl  = url('index/api/payment', ['code'=>'kqpay'], false, true);
        $this->rtnUrl = url('member/payment/show', ['code'=>'kqpay'], false, true);
    }

    /**
     * 	 根据订单信息进行快钱支付需要的信息整合 
     * 	 @var $order
     */
    public function send_info($payment_info, $order)
    {
        //交易总额
        $orderAmount = 0;
        foreach ($order['order_list'] as $key => $val) {
            $orderAmount += $val['order_amount'];
        }
        /**
         * 交易参数
         */
        $parameter = array(
            'inputCharset' => "1", //编码方式，1代表 UTF-8; 2 代表 GBK; 3代表 GB2312 默认为1,该参数必填。
            'bgUrl' => $this->bgUrl, //服务器接收快钱支付结果地址
            'version' => "v2.0", //网关版本，固定值：v2.0,该参数必填。
            'language' => "1", //语言种类，1代表中文显示，2代表英文显示。默认为1,该参数必填。
            'signType' => "4", //签名类型,该值为4，代表PKI加密方式,该参数必填。
            'merchantAcctId' => $payment_info['payment_config']['kqpay_merchantacctid'], //商户人民币网关账号
            'payerContactType' => "1", //支付人联系类型，1 代表电子邮件方式；2 代表手机联系方式。可以为空。
            'payerContact' => $payment_info['payment_config']['payer_contact'], //支付人联系方式，与payerContactType设置对应，payerContactType为1，则填写邮箱地址；payerContactType为2，则填写手机号码。可以为空。
            'orderId' => $order['pay_sn'], //$order['orderid']订单号
            'orderAmount' => $orderAmount * 100, //将金额变成元
            'orderTime' => date("YmdHis"),
            'payerName' => $order['buyer_name'], //支付人姓名,可以为空。
            'productName' => '购买支付', //商品名称，可以为空。
            'productNum' => '1', //商品数量，可以为空。
            'productDesc' => '描述', //商品描述，可以为空
            'ext1' => $order['order_type'], //拓展字段，存储支付的方式 kqpay
            'ext2' => "", //扩展自段2，商户可以传递自己需要的参数，支付完快钱会原值返回，可以为空。
            'payType' => "00", //支付方式，一般为00，代表所有的支付方式。如果是银行直连商户，该值为10，必填。
            'bankId' => "", //银行代码，如果payType为00，该值可以为空；如果payType为10，该值必须填写，具体请参考银行列表。
            'redoFlag' => "", //同一订单禁止重复提交标志，实物购物车填1，虚拟产品用0。1代表只能提交一次，0代表在支付不成功情况下可以再提交。可为空。
            'pid' => "", //快钱合作伙伴的帐户号，即商户编号，可为空。
        );

        // signMsg 签名字符串 不可空，生成加密签名串

        foreach ($parameter as $key => $val) {
            $kq_all_para .= $this->kq_ck_null($val, $key);
        }
        $kq_all_para = substr($kq_all_para, 0, strlen($kq_all_para) - 1);

        /////////////  RSA 签名计算 ///////// 开始 //
        $fp = fopen(__DIR__ . '/kqpay/ayg-rsa.pem', "r");
        $priv_key = fread($fp, 123456);
        fclose($fp);
        $pkeyid = openssl_get_privatekey($priv_key);
        // compute signature
        openssl_sign($kq_all_para, $parameter['signMsg'], $pkeyid, OPENSSL_ALGO_SHA1);

        // free the key from memory
        openssl_free_key($pkeyid);

        $parameter['signMsg'] = base64_encode($parameter['signMsg']);
        /////////////  RSA 签名计算 ///////// 结束 //

        $html = '<html><head></head><body>';
        $html .= '<form method="post" name="kqPay" action="' . $this->payUrl . '">';
        foreach ($parameter as $key => $val) {
            $html .= "<input type='hidden' name='$key' value='$val' />";
        }
        $html .= '</form><script type="text/javascript">document.kqPay.submit();</script>';
        $html .= '</body></html>';
        echo $html;
        exit;
    }

    /**
     * 快钱将信息返回至revieve方法中
     */
    public function return_verify()
    {
        //人民币网关账号，该账号为11位人民币网关商户编号+01,该值与提交时相同。
        if (isset($_REQUEST['merchantAcctId'])) {
            $kq_check_all_para = $this->kq_ck_null($_REQUEST['merchantAcctId'], 'merchantAcctId');
        }
        //网关版本，固定值：v2.0,该值与提交时相同。
        if (isset($_REQUEST['version'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['version'], 'version');
        }
        //语言种类，1代表中文显示，2代表英文显示。默认为1,该值与提交时相同。
        if (isset($_REQUEST['language'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['language'], 'language');
        }
        //签名类型,该值为4，代表PKI加密方式,该值与提交时相同。
        if (isset($_REQUEST['signType'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['signType'], 'signType');
        }
        //支付方式，一般为00，代表所有的支付方式。如果是银行直连商户，该值为10,该值与提交时相同。
        if (isset($_REQUEST['payType'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['payType'], 'payType');
        }
        //银行代码，如果payType为00，该值为空；如果payType为10,该值与提交时相同。
        if (isset($_REQUEST['bankId'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['bankId'], 'bankId');
        }
        //商户订单号，,该值与提交时相同。
        if (isset($_REQUEST['orderId'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['orderId'], 'orderId');
        }
        //订单提交时间，格式：yyyyMMddHHmmss，如：20071117020101,该值与提交时相同。
        if (isset($_REQUEST['orderTime'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['orderTime'], 'orderTime');
        }
        //订单金额，金额以“分”为单位，商户测试以1分测试即可，切勿以大金额测试,该值与支付时相同。
        if (isset($_REQUEST['orderAmount'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['orderAmount'], 'orderAmount');
        }
        // 快钱交易号，商户每一笔交易都会在快钱生成一个交易号。
        if (isset($_REQUEST['dealId'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['dealId'], 'dealId');
        }
        //银行交易号 ，快钱交易在银行支付时对应的交易号，如果不是通过银行卡支付，则为空
        if (isset($_REQUEST['bankDealId'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['bankDealId'], 'bankDealId');
        }
        //快钱交易时间，快钱对交易进行处理的时间,格式：yyyyMMddHHmmss，如：20071117020101
        if (isset($_REQUEST['dealTime'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['dealTime'], 'dealTime');
        }
        //商户实际支付金额 以分为单位。比方10元，提交时金额应为1000。该金额代表商户快钱账户最终收到的金额。
        if (isset($_REQUEST['payAmount'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['payAmount'], 'payAmount');
        }
        //费用，快钱收取商户的手续费，单位为分。
        if (isset($_REQUEST['fee'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['fee'], 'fee');
        }
        //扩展字段1，该值与提交时相同
        if (isset($_REQUEST['ext1'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['ext1'], 'ext1');
        }
        //扩展字段2，该值与提交时相同。
        if (isset($_REQUEST['ext2'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['ext2'], 'ext2');
        }
        //处理结果， 10支付成功，11 支付失败，00订单申请成功，01 订单申请失败
        if (isset($_REQUEST['payResult'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['payResult'], 'payResult');
        }
        //错误代码 ，请参照《人民币网关接口文档》最后部分的详细解释。
        if (isset($_REQUEST['errCode'])) {
            $kq_check_all_para .= $this->kq_ck_null($_REQUEST['errCode'], 'errCode');
        }
        $trans_body = substr($kq_check_all_para, 0, strlen($kq_check_all_para) - 1);
        if (isset($_REQUEST['signMsg'])) {
            $MAC = base64_decode($_REQUEST['signMsg']);
        }

        $fp = fopen(__DIR__ . "/kqpay/ayg-rsa.pem", "r");
        $cert = fread($fp, 123456);
        fclose($fp);
        $pubkeyid = openssl_get_publickey($cert);
        $ok = openssl_verify($trans_body, $MAC, $pubkeyid);

        if ($ok == 1) {
            switch ($_REQUEST['payResult']) {
                case '10':
                    //以下是我们快钱设置的show页面，商户需要自己定义该页面。
                    $this->rtnUrl = $this->rtnUrl . "?msg=success";
                    $this->pay_result = true;
                    return true;
                    break;
                default:
                    //以下是我们快钱设置的show页面，商户需要自己定义该页面。
                    $this->rtnUrl = $this->rtnUrl . "?msg=false";
                    return false;
                    break;
            }
        } else {
            //以下是我们快钱设置的show页面，商户需要自己定义该页面。
            $this->rtnUrl = $this->rtnUrl . "?msg=error";
            return false;
        }
    }

    /**
     * 取得订单支付状态，成功或失败
     *
     * @param array $param
     * @return array
     */
    public function getPayResult($param)
    {
        return $this->pay_result;
    }

    /**
     * 获得最后show页面的地址
     */
    public function getRtnUrl()
    {
        return $this->rtnUrl;
    }

    function kq_ck_null($kq_va, $kq_na)
    {
        if ($kq_va == "") {
            $kq_va = "";
        } else {
            return $kq_va = $kq_na . '=' . $kq_va . '&';
        }
    }

}
